#include <ctype.h>
#include <stdio.h>

#define COLUMNS 15

void print_interval();
void print_head();

typedef unsigned char BYTE;

int main() {
  void *address;
  int n, i;
  BYTE *ptr;

  printf("Address of main function: 0x%p\n", main);
  printf("Address of address variable: 0x%p\n", &address);

  printf("Enter a hex address: ");
  scanf("%p", &address);

  printf("Enter number of bytes to view: ");
  scanf("%d", &n);

  printf("\n");

  print_head();

  ptr = (BYTE *)address;
  for (; n > 0; n -= COLUMNS) {
    printf("%p", ptr);
    print_interval();

    for (i = 0; i < COLUMNS && i < n; i++)
      printf("%.2X ", *(ptr + i));
    // 如果一行不满,用空格填充
    for (; i < COLUMNS; i++)
      print_interval();

    print_interval();

    for (i = 0; i < COLUMNS && i < n; i++) {
      BYTE ch = *(ptr + i);
      if (!isprint(ch))
        ch = '.';
      printf("%c", ch);
    }

    printf("\n");
    ptr += COLUMNS;
  }

  return 0;
}

// 打印3个空格作为间隔
void print_interval() { printf("   "); }

// 打印表头
void print_head() {
  int i, num_of_space;

  // 第一行表头
  printf("     offset     ");
  print_interval();

  num_of_space = (3 * COLUMNS - sizeof("Bytes")) / 2;

  for (i = 0; i < num_of_space; i++)
    printf(" ");
  printf("Bytes");
  for (i = 0; i < num_of_space; i++)
    printf(" ");

  if ((3 * COLUMNS - sizeof("Bytes")) % 2)
    printf(" ");

  print_interval();

  num_of_space = (COLUMNS - sizeof("characters")) / 2;
  printf(" ");
  for (i = 0; i < num_of_space; i++)
    printf(" ");
  printf("characters");
  for (i = 0; i < num_of_space; i++)
    printf(" ");

  if ((COLUMNS - sizeof("characters")) % 2)
    printf(" ");

  printf("\n");

  // 分割线
  printf("----------------");
  print_interval();

  for (i = 0; i < COLUMNS * 3 - 1; i++)
    printf("-");

  print_interval();

  printf(" ");
  for (i = 0; i < COLUMNS; i++)
    printf("-");

  printf("\n");
}